package com.csair.platform.cit.service.util;

import com.csair.invoice.common.base.util.CastUtil;
import com.csair.platform.cit.facade.exception.CitBizException;
import com.csair.platform.cit.service.annotation.Jpath;
import com.csair.platform.cit.service.annotation.JpathPrefix;

import java.lang.reflect.Field;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author zhengxincheng
 */
public class JpathUtils {

    /**
     * 根据Object获取Jpath路径
     * @param
     * @return
     */
    public static String getJpath(Object t){
        List<Map<String,Object>> lists = sort(getJpathFieldValues(t));
        String prefix = getJpathPrefixValue(t).get("prefix");

        return formatJpath(prefix,lists);
    }
    /**
     * 根据list获取jpath
     * @param list
     * @return
     */
    public static String getJpath(List list){
        StringBuffer jpath = new StringBuffer();
        for (int i = 0; i < list.size(); i++) {
            List<Map<String,Object>> lists = sort(getJpathFieldValues(list.get(i)));
            String prefix = getJpathPrefixValue(list.get(i)).get("prefix");
            jpath.append(formatJpath(prefix,lists,i));
        }
        return jpath.toString();
    }
    /**
     *  // \"kz_.temp.cgwgqyxxbgbVO[0].gdxxGrid.gdxxGridlb[0].cgbl\":\"0.00\",
     */
    public static String getJpath(List data,int number){
        StringBuffer jpath = new StringBuffer();
        for (int i = 0; i < data.size(); i++) {
            List<Map<String,Object>> lists = sort(getJpathFieldValues(data.get(i)));
            Map<String,String> map = getJpathPrefixValue(data.get(i));
            String prefix = map.get("prefix");
            String suffix = map.get("suffix");
            jpath.append(formatJpath(prefix,suffix,lists,number,i));
        }
        return jpath.toString();
    }

    /**
     *
     * @param prefix 前缀名称
     * @param suffix 后缀
     * @param lists  数据集合
     * @param number 前下标
     * @param index  后下表
     * @return
     */
    public static String formatJpath(String prefix,String suffix,List<Map<String,Object>> lists,int number,int index){
        StringBuffer jpath = new StringBuffer();
        for (Map<String, Object> map : lists) {
            boolean isStr = (boolean) map.get("isStr");
            String fieldName = (String) map.get("fieldName");
            Object fieldValue = isStr ? "\\\""+map.get("fieldValue")+"\\\"" : map.get("fieldValue");
            String path = String.format("%s[%d].%s[%d].%s:%s,",prefix,number,suffix,index,fieldName,fieldValue);
            jpath.append(path);
        }
        return jpath.toString();
    }
    /**
     * 拼装jpath
     * @param prefix 前缀
     * @param lists  值
     * @return jpath路径
     */
    public static String formatJpath(String prefix,List<Map<String,Object>> lists,int index){
        StringBuffer jpath = new StringBuffer();
        for (Map<String,Object> map : lists) {
            boolean isStr = (boolean) map.get("isStr");
            Object fieldValue = isStr ? "\\\""+map.get("fieldValue")+"\\\"" : map.get("fieldValue");
            String path = String.format("\\\"%s["+index+"].%s\\\":%s,",prefix,map.get("fieldName"),fieldValue);
            jpath.append(path);
        }
        return jpath.toString();
    }

    /**
     * 拼装jpath
     * @param prefix 前缀
     * @param lists  值
     * @return jpath路径
     */
    public static String formatJpath(String prefix,List<Map<String,Object>> lists){
        StringBuffer jpath = new StringBuffer();
        for (Map<String,Object> map : lists) {
            boolean isStr = (boolean) map.get("isStr");
            Object fieldValue = isStr ? "\\\""+map.get("fieldValue")+"\\\"" : map.get("fieldValue");
            String path = String.format("\\\"%s.%s\\\":%s,",prefix,map.get("fieldName"),fieldValue);
            jpath.append(path);
        }
        return jpath.toString();
    }

    public static List<Map<String, Object>> sort(List<Map<String, Object>> list){
        if(list.isEmpty()){
            return list;
        }
        List<Map<String, Object>> r = list.stream().sorted(Comparator.comparing(map ->(int) map.get("sort"))).collect(Collectors.toList());
        return r;
    }
    /**
     * 打印jpath在控制台
     * @param jpath
     */
    public static void printFormatJpath(String jpath){
        String [] strs = jpath.split(",");
        for (String str : strs) {
            System.err.println(str+",");
        }
    }


    /**
     * 获取@JpathPrefix(prefix = "") 属性值
     * @param param
     * @return
     */
    public static Map<String, String> getJpathPrefixValue(Object param) {
        Class obj = param.getClass();
        Map<String, String> map = new HashMap<>();
        JpathPrefix jpathPrefix = (JpathPrefix) obj.getAnnotation(JpathPrefix.class);
        if(Objects.isNull(jpathPrefix)){
            String exName = String.format("目标类[%s]没有@JpathPrefix注解",param.getClass().getName());
            throw new CitBizException(7008,exName);
        }
        map.put("prefix",jpathPrefix.prefix());
        map.put("suffix",jpathPrefix.suffix());
        return map;
    }

    /**
     *  @Jpath(name = "",isStr = true,sort = 1)
     *  1. 获取属性值
     *  name,isStr,sort值封装到一个List<Map<String,Object>>
     * @param param
     * @return
     */
    public static List<Map<String,Object>> getJpathFieldValues(Object param)  {
        List<Map<String,Object>> list = new ArrayList();
        Class obj = param.getClass();
        for (Field field:obj.getDeclaredFields()) {
            field.setAccessible(true);
            Jpath jpath = field.getAnnotation(Jpath.class);
            if(jpath != null) {
                Map<String,Object> rMap = new HashMap<>();
                Object fieldValue = null;
                try {
                    fieldValue = field.get(param);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }
                if(Objects.isNull(fieldValue)){
                    if(jpath.isStr()){
                        fieldValue = CastUtil.castString(fieldValue);
                    }else{
                        fieldValue = 0;
                    }
                }
                rMap.put("fieldName",field.getName());
                rMap.put("fieldValue",fieldValue);
                rMap.put("isStr", jpath.isStr());
                rMap.put("sort",jpath.sort());
                list.add(rMap);
            }
        }
        if(list.isEmpty()){
            String exName = String.format("目标类[%s]没有@Jpath注解",param.getClass().getName());
            throw new CitBizException(7009,exName);
        }
        return list;
    }
}
